﻿using System;
using System.IO;
using System.Windows.Forms;
using DigitalRune.Windows.TextEditor;
using DigitalRune.Windows.TextEditor.Actions;
using DigitalRune.Windows.TextEditor.Completion;
using DigitalRune.Windows.TextEditor.Highlighting;
using DigitalRune.Windows.TextEditor.Selection;
using EmbeddedSharp.Core;
using EmbeddedSharp.Core.Function;
using Zove.Runtime;
using EmbeddedSharp.Scripting.Function;
using Zove.Runtime.Core;

namespace Zove.Desktop {
    public partial class EditingForm : AbstractDesktopForm, IModelling {

        public string ClassName {
            get;
            set;
        }

        public RunWindow RunningInstance {
            get;
            set;
        }

        /// <summary>
        /// 
        /// </summary>
        public void GotoDefinition() {
            if (base.Selections.Count < 1) {
                return;
            }

            ISelection selection = base.Selections[0];
            if (selection.Offset <
                this.GetTextEditorControl().Text.Length
                && this.GetTextEditorControl().Text[
                selection.EndOffset] == '(') {
                // show 

                string summary = string.Empty;
                FuncNode fn = ZoveDependencyManager.Instance.FunctionManager.GetFunction(
                    selection.SelectedText);
                if (fn == null) {
                    MessageBox.Show("No information is available for the selected function.");
                } else if (fn is UserDefinedFunctionNode) {
                    UserDefinedFunctionNode udf
                        = (UserDefinedFunctionNode)fn;
                    summary = udf.Comment;
                    if (string.IsNullOrEmpty(summary)) {
                        MessageBox.Show("The summary for the function is left blank");
                    } else {
                        MessageBox.Show(summary);
                    }
                } else {
                    string helpFileName
                        = ZoveDependencyManager.GetFileFile(
                        selection.SelectedText);
                    if (helpFileName != null) {
                        if (File.Exists(helpFileName)) {
                            HelpWindow hw = new HelpWindow(helpFileName);

                            ((Form1)this.MdiParent).ShowWindow(hw);
                        } else {
                            MessageBox.Show("Cannot find the correpsonded help text for function " + selection.SelectedText);
                        }
                    } else {
                        MessageBox.Show(
                            "Cannot find correpsonded help text for function "
                            + selection.SelectedText);
                    }
                }
            } else {
                ((Form1)this.MdiParent).OpenEditWindow(base.SelectedText);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public EditingForm()
            : base() {
            this.teSource.LineViewerStyle = DigitalRune.Windows.TextEditor.Properties.LineViewerStyle.FullRow;

            this.teSource.ContextMenuStrip = this.cmsEditing;
            this.GetTextEditorControl().Document.HighlightingStrategy
                = HighlightingManager.Manager.FindHighlighter("Zoom");
            if (!string.IsNullOrEmpty(
                DesktopUtils.ModelTemplateFile)
                &&
                File.Exists(
                DesktopUtils.ModelTemplateFile)) {
                this.GetTextEditorControl().Document.TextContent
                = File.ReadAllText(DesktopUtils.ModelTemplateFile);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void Cut() {
            Cut cut = new Cut();
            cut.Execute(this.GetTextEditorControl());
        }

        /// <summary>
        /// 
        /// </summary>
        public void Copy() {
            Copy cut = new Copy();
            cut.Execute(this.GetTextEditorControl());
        }

        /// <summary>
        /// 
        /// </summary>
        public void Paste() {
            Paste cut = new Paste();
            cut.Execute(this.GetTextEditorControl());
        }

        /// <summary>
        /// 
        /// </summary>
        public void Delete() {
            Delete cut = new Delete();
            cut.Execute(this.GetTextEditorControl());
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        public EditingForm(string fileName)
            : this() {
            FileInfo fi = new FileInfo(fileName);
            this.ClassName = GetClassName(fileName);
            this.FileName = fileName;
            this.Text = fi.Name;
            this.ToolTipText = fileName;
            this.GetTextEditorControl().Document.TextContent
                = File.ReadAllText(fileName);
            base.IsDirty = false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string GetFileExtension() {
            return ".zoom";
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CompletionRequest(object sender, CompletionEventArgs e) {
            if (this.GetTextEditorControl().CompletionWindowVisible) {
                return;
            }

            if (e.Key == '\0') {
                this.GetTextEditorControl().ShowCompletionWindow(
                    new CodeCompletionDataProvider(), e.Key, false);
            } else if (char.IsLetter(e.Key)) {
                this.GetTextEditorControl().ShowCompletionWindow(
                    new CodeCompletionDataProvider(), e.Key, true);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static string GetClassName(string fileName) {
            int lastDot = fileName.LastIndexOf('.');
            if (lastDot > 0) {
                int last = fileName.LastIndexOf('\\');
                return fileName.Substring(last + 1, lastDot - last - 1);
            }

            return fileName;
        }

        public Zove.DesignTime.ZoomClass Class {
            get {
                DefaultClassLoader cl
                    = new DefaultClassLoader();
                Zove.DesignTime.ZoomClass c = cl.LoadFromSource(this.Source);

                return c;
            }
        }

        public void Validate() {

        }

        /// <summary>
        /// 
        /// </summary>
        public virtual void Run() {
            //try {
            if (this.RunningInstance == null) {
                this.RunningInstance = new RunWindow(Class);
                this.RunningInstance.MdiParent = this.MdiParent;
                this.RunningInstance.Editor = this;
                this.RunningInstance.FormClosing
                    += new FormClosingEventHandler(
                        ((Form1)this.MdiParent).RemoveWindowItem);
                this.RunningInstance.Show(this.DockPanel);
            } else {
                this.RunningInstance.BringToFront();
            }

            ((Form1)this.MdiParent).AddWindowMenuItem(
                this.RunningInstance, WindowType.Run);
            //} catch (Exception ex) {
            //    MessageBox.Show(ex.Message);
            //}
        }

        public override TextEditorControl GetTextEditorControl() {
            return this.teSource;
        }

        public override string GetFileFilter() {
            return "Zoom file (*.zoom) | *.zoom |HTML file (*.html) | *.html";
        }

        public override string GetColourScheme() {
            return "Zoom";
        }

        private void cutToolStripMenuItem_Click(object sender, EventArgs e) {
            Cut();
        }

        private void copyToolStripMenuItem_Click(object sender, EventArgs e) {
            Copy();
        }

        private void pasteToolStripMenuItem_Click(object sender, EventArgs e) {
            Paste();
        }

        private void deleteToolStripMenuItem_Click(object sender, EventArgs e) {
            Delete();
        }
    }
}
